package pritace

import (
	"fmt"
	"sort"
	"sync"
)

func testMain() {

	// newMap()
	// sliceMap()
	// foreachMap()
	// delMap()
	syncMap()
}

func newMap() {

	var mapLit map[string]int
	var mapAssigned map[string]int
	mapLit = map[string]int{"one": 1, "two": 2}
	mapCreated := make(map[string]float32)
	mapAssigned = mapLit
	mapCreated["key1"] = 4.5
	mapCreated["key2"] = 3.14159
	mapAssigned["two"] = 3

	fmt.Printf("Map literal at \"one\" is: %d\n", mapLit["one"])
	fmt.Printf("Map created at \"key2\" is: %f\n", mapCreated["key2"])
	fmt.Printf("Map assigned at \"two\" is: %d\n", mapLit["two"])
	fmt.Printf("Map literal at \"ten\" is: %d\n", mapLit["ten"])

}

func sliceMap() {
	mp1 := make(map[int][]int)
	mp1[1] = []int{2, 3, 4}
	fmt.Print(mp1)

}

func foreachMap() {
	// 遍历输出元素的顺序与填充顺序无关，不能期望 map 在遍历时返回某种期望顺序的结果
	scene := make(map[string]int)
	scene["route"] = 64
	scene["brazil"] = 4
	scene["china"] = 960
	/*****第一种遍历方式*****/
	// for k, v := range scene {
	// 	fmt.Println(k, v)
	// }
	/*****第二种遍历方式*****/
	// for _, v := range scene {
	// 	fmt.Println(v)
	// }
	/*****只遍历键的方式*****/
	// for k := range scene {
	// 	fmt.Println(k)
	// }

	//如果需要特定顺序的遍历结果，正确的做法是先排序
	// sceneList := make([]string, 2)
	var sceneList []string
	for k := range scene {
		sceneList = append(sceneList, k)
	}

	sort.Strings(sceneList)
	fmt.Println(sceneList)
}

func delMap() {
	scene := make(map[string]int)
	scene["bob"] = 1
	scene["mia"] = 2
	scene["lynn"] = 3

	delete(scene, "bob")

	for k := range scene {
		fmt.Println(k)
	}

}

func syncMap() {
	var scene sync.Map

	scene.Store("bob", 1)
	scene.Store("ivan", 2)
	scene.Store("mia", 3)

	scene.Range(func(key, value interface{}) bool {
		fmt.Print(key)
		return true
	})
	scene.Delete("ivan")
	scene.Range(func(key, value any) bool {
		fmt.Println(key)
		return true //只有为ture的情况下才能接着遍历
	})
}

var valueKey = make(map[string]int)
var valueByKeyGuard sync.Mutex

//加锁的方式获取map中的一个值，防止并发
func readMapValue(key string) int {

	valueByKeyGuard.Lock()
	v := valueKey[key]
	valueByKeyGuard.Unlock()
	return v
}

//通过defer的方式对上面的方法简写
func readMapValue2(key string) int {
	valueByKeyGuard.Lock()
	defer valueByKeyGuard.Unlock()
	return valueKey[key]
}
